package com.jiantong.web.open.app.work;

import com.jiantong.web.core.enums.ExceptionCode;
import com.jiantong.work.dto.ButcherReportDto;
import com.jiantong.work.enums.ButcherReportStatus;
import com.jiantong.work.model.ButcherReport;
import com.jiantong.work.model.ButcherReportCert;
import com.jiantong.work.model.ButcherReportSurveyRecord;
import com.jiantong.work.service.*;
import io.terminus.boot.rpc.common.annotation.RpcConsumer;
import io.terminus.common.model.Paging;
import io.terminus.common.model.Response;
import io.terminus.pampas.openplatform.annotations.OpenBean;
import io.terminus.pampas.openplatform.annotations.OpenMethod;
import io.terminus.pampas.openplatform.exceptions.OPClientException;
import io.terminus.pampas.openplatform.exceptions.OPServerException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.List;
import java.util.Map;

/**
 * Created by niufei on 2017/3/22.
 *
 */
@Slf4j
@OpenBean
public class ButcherReportApis {

    @RpcConsumer
    private ButcherReportReadService butcherReportReadService;

    @RpcConsumer
    private ButcherReportWriteService butcherReportWriteService;

    @RpcConsumer
    private ButcherReportSurveyRecordReadService butcherReportSurveyRecordReadService;

    @RpcConsumer
    private ButcherReportSurveyRecordWriteService butcherReportSurveyRecordWriteService;

    @RpcConsumer
    private CreditProductService creditProductService;

    @RpcConsumer
    private ButcherReportCertWriteService butcherReportCertWriteService;

    @RpcConsumer
    private ButcherReportCertReadService butcherReportCertReadService;

    @OpenMethod(
            key = "find.butcher.report.by.id",
            paramNames = {"id"},
            httpMethods = RequestMethod.GET
    )
    public ButcherReport findButcherReportById(Long id){
        Response<ButcherReport> reportResponse = butcherReportReadService.findById(id);
        if(!reportResponse.isSuccess()){
            log.error("failed to find ButcherReport , cause : {}", reportResponse.getError());
            throw new OPServerException(reportResponse.getError());
        }
        return reportResponse.getResult();
    }

    @OpenMethod(
            key = "paging.butcher.report",
            paramNames = {"pageNo","pageSize","statuses"},
            httpMethods = RequestMethod.GET
    )
    public Paging<ButcherReport> pagingButcherReport(Integer pageNo, Integer pageSize,List<Integer> statuses){
        Response<Paging<ButcherReport>> pagingResponse = butcherReportReadService.pagingButcherReport(pageNo,pageSize,statuses);
        if(!pagingResponse.isSuccess()){
            log.error("failed to paging ButcherReport , cause : {}", pagingResponse.getError());
            throw new OPServerException(pagingResponse.getError());
        }
        return pagingResponse.getResult();
    }

    @OpenMethod(
            key = "create.butcher.report",
            paramNames = {"butcherReport","toStatus","remainderEars"},
            httpMethods = RequestMethod.POST
    )
    public Map<String , Object> createButcherReport(ButcherReport butcherReport, Integer toStatus,List<String> remainderEars){
        Response<Map<String , Object>> response = butcherReportWriteService.create(butcherReport,toStatus,remainderEars);
        if(!response.isSuccess()){
            log.error("failed to create butcherReport error = {}, cause : {}", butcherReport, response.getError());
            throw new OPServerException(response.getError());
        }
        return response.getResult();
    }


    @OpenMethod(
            key = "update.butcher.report",
            paramNames = {"butcherReport","toStatus","remainderEars"},
            httpMethods = RequestMethod.PUT
    )
    public Map<String , Object> updateButcherReport(ButcherReport butcherReport, Integer toStatus,List<String> remainderEars){
        if(butcherReport.getId() == null){
            log.error("failed to update butcherReport error = {}, cause : {}", butcherReport,butcherReport.getId());
            throw new OPClientException("butcherReport.id.is.null");
        }
        Response<Map<String , Object>> statusResponse = butcherReportReadService.findStatusById(butcherReport.getId());
        if(statusResponse.isSuccess() && !statusResponse.getResult().get("status").equals(butcherReport.getStatus())){
            log.error("failed to update butcherReport error={}, cause : {}",butcherReport.getStatus(),statusResponse.getResult().get("status"));
            throw new OPClientException("butcherReport.id.is.already.submitted");
        }
        Response<Map<String , Object>> response = butcherReportWriteService.update(butcherReport, toStatus,remainderEars);
        if(!response.isSuccess()){
            log.error("failed to update butcherReport error = {}, cause : {}", butcherReport, response.getError());
            throw new OPServerException(response.getError());
        }
        return response.getResult();
    }

    @OpenMethod(
            key = "find.butcher.report.and.survey.record.by.report.id",
            paramNames = {"id"},
            httpMethods = RequestMethod.GET
    )
    public ButcherReportDto findByReportId(Long id){
        ButcherReportDto butcherReportDto = new ButcherReportDto();

        Response<ButcherReport> butcherReportResponse = butcherReportReadService.findById(id);
        if(!butcherReportResponse.isSuccess()){
            log.error("failed to find butcherReport by id = {}, cause : {}", id, butcherReportResponse.getError());
            throw new OPServerException(butcherReportResponse.getError());
        }
        butcherReportDto.setButcherReport(butcherReportResponse.getResult());

        Long surveyRecordId = butcherReportSurveyRecordReadService.findIdByReportId(id);
        if(surveyRecordId != null){
            Response<ButcherReportSurveyRecord> butcherReportSurveyRecordResponse = butcherReportSurveyRecordReadService.findByReport(id);
            if(!butcherReportSurveyRecordResponse.isSuccess()){
                log.error("failed to find butcherReportSurveyRecord by id = {}, cause : {}", id, butcherReportSurveyRecordResponse.getError());
                throw new OPServerException(butcherReportSurveyRecordResponse.getError());
            }
            butcherReportDto.setButcherReportSurveyRecord(butcherReportSurveyRecordResponse.getResult());
        }else{
            butcherReportDto.setButcherReportSurveyRecord(new ButcherReportSurveyRecord());
        }
        return Response.ok(butcherReportDto).getResult();
    }

    @OpenMethod(
            key = "save.butcher.report.and.survey.record",
            paramNames = {"butcherReport","butcherReportSurveyRecord","toStatus"},
            httpMethods = RequestMethod.POST
    )
    public Map<String , Object> saveButcherReportAndSurveyRecord(ButcherReport butcherReport, ButcherReportSurveyRecord butcherReportSurveyRecord, Integer toStatus){
        if(butcherReport.getId() == null){
            log.error("failed to update butcherReport error={}, cause : {}",butcherReport,butcherReport.getId());
            throw new OPClientException("butcherReport.id.is.null");
        }

        Response<Map<String,Object>> statusResponse = butcherReportReadService.findStatusById(butcherReport.getId());
        if(statusResponse.isSuccess() && !statusResponse.getResult().get("status").equals(butcherReport.getStatus())){
            log.error("failed to update butcherReport error={}, cause : {}",butcherReport.getStatus(),statusResponse.getResult().get("status"));
            throw new OPClientException("butcherReport.id.is.already.submitted");
        }

        if(!toStatus.equals(ButcherReportStatus.ANTEMORTEM_INSPECTION.value())
                && !butcherReport.getStatus().equals(ButcherReportStatus.STAY_APPROVE.value())
                && butcherReportSurveyRecord.getId() == null){
            log.error("failed to update butcherReportSurveyRecord error={}, cause : {}",butcherReportSurveyRecord,butcherReportSurveyRecord.getId());
            throw new OPClientException("butcherReportSurveyRecord.id.is.null");
        }

        Response<Map<String , Object>> response = butcherReportSurveyRecordWriteService.saveButcherReportAndSurveyRecord(butcherReport,butcherReportSurveyRecord,toStatus);
        if(!response.isSuccess()){
            log.error("failed to save butcherReportSurveyRecord and butcherReport  error = {}, cause : {}", butcherReportSurveyRecord,butcherReport, response.getError());
            throw new OPServerException(response.getError());
        }
        return response.getResult();
    }

    @OpenMethod(
            key = "find.butcher.report.cert.by.id",
            paramNames = {"id"},
            httpMethods = RequestMethod.GET
    )
    public ButcherReportCert findButcherReportCertById(Long id){
        Response<ButcherReportCert> response = butcherReportCertReadService.findButcherReportCertById(id);
        if(!response.isSuccess()){
            log.error("failed to find butcher report cert id = {}",id,response.getError());
            throw new OPServerException(response.getError());
        }
        return response.getResult();
    }

    @OpenMethod(
            key = "paging.butcher.report.cert",
            paramNames = {"pageNo","pageSize","reportId","reportNumber"},
            httpMethods = RequestMethod.GET
    )
    public Paging<ButcherReportCert> pagingButcherReportCert(Integer pageNo ,Integer pageSize,
                                                             Long reportId,String reportNumber){
        Response<Paging<ButcherReportCert>> response =
                butcherReportCertReadService.pagingButcherReportCert(pageNo,pageSize,reportId,reportNumber);
        if(!response.isSuccess()){
            log.error("failed to paging butcher report cert",response.getError());
            throw new OPServerException(response.getError());
        }
        return response.getResult();
    }

    @OpenMethod(
            key = "create.a.butcher.report.cert",
            paramNames = {"butcherReportCert"},
            httpMethods = RequestMethod.POST
    )
    public Long create(ButcherReportCert butcherReportCert){

        if(butcherReportCert == null){
            log.error("butcherReportCert must be not null");
            throw new OPClientException(ExceptionCode.OBJECT_NOT_EXIST.value(),"butcherReportCert must be not null");
        }

        Response<Long> response = butcherReportCertWriteService.create(butcherReportCert);
        if(!response.isSuccess()){
            log.error("failed to add a record , case = {}",response.getError());
            throw new OPServerException(ExceptionCode.DATA_WRITE_FAIL.value(),response.getError());
        }

        return response.getResult();
    }

    @OpenMethod(
            key = "creates.multi.butcher.report.certs",
            paramNames = {"butcherReportCerts"},
            httpMethods = RequestMethod.POST
    )
    public Integer createsForApp(List<Map<String,Object>> butcherReportCerts){
        if(butcherReportCerts == null || butcherReportCerts.isEmpty()){
            log.error("butcherReportCerts must be not null");
            throw new OPClientException(ExceptionCode.OBJECT_NOT_EXIST.value(),"butcherReportCerts must be not null");
        }

        Response<Integer> response = butcherReportCertWriteService.creates(butcherReportCerts);

        if(!response.isSuccess()){
            log.error("failed to add multi records , case = {}",response.getError());
            throw new OPServerException(ExceptionCode.DATA_WRITE_FAIL.value(),response.getError());
        }

        return response.getResult();
    }
}
